package com.syezon.wifikey.speed;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.syezon.wifikey.R;
import com.syezon.wifikey.base.BaseFragment;
import com.syezon.wifikey.view.SpeedTestView;

import java.text.DecimalFormat;

import butterknife.BindView;
import butterknife.OnClick;


public class SpeedTestFragment extends BaseFragment {

    @BindView(R.id.tv_delay_result)
    TextView mTvDelayResult;
    @BindView(R.id.iv_delay_check)
    ImageView mIvDelayCheck;
    @BindView(R.id.tv_delay)
    TextView mTvDelay;
    @BindView(R.id.tv_download_speed_result)
    TextView mTvDownloadResult;
    @BindView(R.id.iv_download_speed_check)
    ImageView mIvDownloadCheck;
    @BindView(R.id.tv_download_speed)
    TextView mTvDownloadSpeed;
    @BindView(R.id.tv_upload_speed_result)
    TextView mTvUploadResult;
    @BindView(R.id.iv_upload_speed_check)
    ImageView mIvUploadCheck;
    @BindView(R.id.tv_upload_speed)
    TextView mTvUploadSpeed;
    @BindView(R.id.tv_state)
    TextView mTvState;

    @BindView(R.id.speed_test_view)
    SpeedTestView mSpeedTestView;
    @BindView(R.id.tv_test_state)
    TextView mTvTestState;

    private String mSsid;

    private int netDelay;
    private double downloadSpeed;
    private double uploadSpeed;
    private SpeedTestViewModel speedTestViewModel;
    private SpeedTestFinishListener mFinishListener;

    public SpeedTestFragment() {
    }


    public static SpeedTestFragment newInstance(String ssid) {
        SpeedTestFragment fragment = new SpeedTestFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        fragment.setSsid(ssid);
        return fragment;
    }

    public void setSsid(String ssid) {
        this.mSsid = ssid;
    }

    public void setFinishListener(SpeedTestFinishListener listener) {
        this.mFinishListener = listener;
    }

    @Override
    protected int getContentViewLayoutID() {
        return R.layout.fragment_speed_test;
    }

    @Override
    protected void initViewsAndEvents() {
        super.initViewsAndEvents();
        mTvTestState.setEnabled(true);
        mIvDelayCheck.setVisibility(View.GONE);
        mIvDownloadCheck.setVisibility(View.GONE);
        mIvUploadCheck.setVisibility(View.GONE);
        speedTestViewModel = ViewModelProviders.of(this).get(SpeedTestViewModel.class);
        speedTestViewModel.getNetDelayLiveData().observe(this, new Observer<Integer>() {
            @Override
            public void onChanged(@Nullable Integer integer) {
                netDelayResult(integer);
            }
        });
        speedTestViewModel.getDownloadSpeedLiveData().observe(this, new Observer<Double>() {
            @Override
            public void onChanged(@Nullable Double aDouble) {
                downloadResult(aDouble);
            }
        });
        speedTestViewModel.getUploadSpeedLiveData().observe(this, new Observer<Double>() {
            @Override
            public void onChanged(@Nullable Double aDouble) {
                uploadResult(aDouble);
            }
        });
        speedTestViewModel.getCurrentSpeedLiveData().observe(this, new Observer<Double>() {
            @Override
            public void onChanged(@Nullable Double aDouble) {
                mSpeedTestView.setCreditValue(aDouble.intValue());
            }
        });
        speedTestViewModel.startTest();
        testNetDelay();
    }

    @OnClick({R.id.tv_test_state})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.tv_test_state:
                if (mFinishListener != null) {
                    mFinishListener.cancel();
                }
                break;
        }
    }

    private void testNetDelay() {
        mIvDelayCheck.setVisibility(View.VISIBLE);
        startAnim(mIvDelayCheck);
        mTvDelayResult.setVisibility(View.GONE);
        mTvState.setText("网络延迟检测中");
    }

    private void netDelayResult(int netDelay) {
        mIvDelayCheck.setVisibility(View.GONE);
        mTvDelayResult.setVisibility(View.VISIBLE);
        mTvDelayResult.setText(netDelay + "ms");
        testDownloadSpeed();
        this.netDelay = netDelay;
    }

    private void testDownloadSpeed() {
        mSpeedTestView.setCreditValue(0);
        mTvDownloadResult.setVisibility(View.GONE);
        startAnim(mIvDelayCheck);
        mIvDownloadCheck.setVisibility(View.VISIBLE);
        mTvState.setText("下载速度检测中");
    }

    private void downloadResult(double speed) {
        mSpeedTestView.setCreditValue(0);
        DecimalFormat decimalFormat = new DecimalFormat("##.##");
        mIvDownloadCheck.setVisibility(View.GONE);
        mTvDownloadResult.setVisibility(View.VISIBLE);
        mTvDownloadResult.setText(decimalFormat.format(speed) + "KB/S");
        testUploadSpeed();
        this.downloadSpeed = speed;
    }

    private void testUploadSpeed() {
        mSpeedTestView.setCreditValue(0);
        mTvUploadResult.setVisibility(View.GONE);
        mIvUploadCheck.setVisibility(View.VISIBLE);
        startAnim(mIvUploadCheck);
        mTvState.setText("上传速度检测中");
    }

    private void uploadResult(double speed) {
        mIvUploadCheck.setVisibility(View.GONE);
        mTvUploadResult.setVisibility(View.VISIBLE);
        DecimalFormat decimalFormat = new DecimalFormat("##.##");
        mTvUploadResult.setText(decimalFormat.format(speed) + "KB/S");
        this.uploadSpeed = speed;
        TestResultInfo testResultInfo = new TestResultInfo();
        testResultInfo.setSsid(mSsid);
        testResultInfo.setNetDelay(netDelay);
        testResultInfo.setDownloadSpeed(downloadSpeed);
        testResultInfo.setUploadSpeed(uploadSpeed);
        if (mFinishListener != null) {
            mFinishListener.finish(testResultInfo);
        }
    }

    private void startAnim(ImageView imageView) {
        final Drawable background = imageView.getBackground();
        if (background != null && background instanceof AnimationDrawable) {
            imageView.post(new Runnable() {
                @Override
                public void run() {
                    ((AnimationDrawable) background).start();
                }
            });
        }
    }

    public static interface SpeedTestFinishListener {
        void finish(TestResultInfo resultInfo);

        void cancel();
    }

}
